package club.janna.study.spring.context;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class JannaClasspathXmlApplicationContext {
    private final String path;

    private Map<String, Object> singletonMap = new ConcurrentHashMap<String, Object>();

    public JannaClasspathXmlApplicationContext(String path) {
        this.path = path;
    }

    /**
     * 通过名称获取bean
     * @param name
     * @param <T>
     * @return
     */
    public <T> T getBean(String name) {
        if(singletonMap.containsKey(name))
            return (T) singletonMap.get(name);
        try {
            return (T) doCreateBean(name);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建bean
     * @param name
     * @return
     */
    public Object doCreateBean(String name) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        Object o = null;
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(path));
        List<Element> elements = document.getRootElement().elements();
        for (Element element : elements) {
            if(!"bean".equals(element.getName()))
                continue;
            List<Attribute> attributes = element.attributes();
            String id = null;
            String cl = null;
            for (Attribute attribute : attributes) {
                if("id".equals(attribute.getName()))
                    id = attribute.getValue();
                if("class".equals(attribute.getName()))
                    cl = attribute.getValue();
            }
            if(id == null || cl == null)
                continue;
            Object o1 = Class.forName(cl).newInstance();
            singletonMap.put(id, o1);
            if(id.equals(name) && o == null)
                o = o1;
        }
        return o;
    }


}
